using System;
using System.Collections.Concurrent;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Primitives;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Timing;
using Matrix.Configuration.Services;
using Matrix.Configuration.DTOs;
using System.Collections.Generic;

namespace Matrix.Configuration.Providers
{
    /// <summary>
    /// Matrix配置提供者，实现ABP Configuration的IConfigurationProvider接口
    /// </summary>
    public class MatrixConfigurationProvider : IConfigurationProvider, ITransientDependency
    {
        private readonly IConfigurationAppService _configurationAppService;
        private readonly IClock _clock;
        private readonly ConcurrentDictionary<string, string> _data;
        private readonly SemaphoreSlim _loadLock;

        public MatrixConfigurationProvider(
            IConfigurationAppService configurationAppService,
            IClock clock)
        {
            _configurationAppService = configurationAppService;
            _clock = clock;
            _data = new ConcurrentDictionary<string, string>(StringComparer.OrdinalIgnoreCase);
            _loadLock = new SemaphoreSlim(1, 1);
        }

        /// <summary>
        /// 获取配置值
        /// </summary>
        public bool TryGet(string key, out string? value)
        {
            // 异步加载配置数据（如果尚未加载）
            _ = LoadConfigurationAsync();

            return _data.TryGetValue(key, out value);
        }

        /// <summary>
        /// 设置配置值
        /// </summary>
        public void Set(string key, string? value)
        {
            _data[key] = value;
        }

        /// <summary>
        /// 获取子键
        /// </summary>
        public IEnumerable<string> GetChildKeys(IEnumerable<string> earlierKeys, string? parentPath)
        {
            _ = LoadConfigurationAsync();

            var keys = new List<string>();

            foreach (var kvp in _data)
            {
                var key = kvp.Key;

                if (parentPath == null)
                {
                    if (key.IndexOf(':') == -1)
                    {
                        keys.Add(key);
                    }
                }
                else
                {
                    if (key.StartsWith(parentPath + ':', StringComparison.OrdinalIgnoreCase))
                    {
                        var remainingKey = key.Substring(parentPath.Length + 1);
                        var firstSegment = remainingKey.IndexOf(':') == -1 ? remainingKey : remainingKey.Substring(0, remainingKey.IndexOf(':'));
                        keys.Add(firstSegment);
                    }
                }
            }

            return keys;
        }

        /// <summary>
        /// 获取重载令牌
        /// </summary>
        public IChangeToken GetReloadToken()
        {
            // 实现配置变更通知
            return new MatrixConfigurationChangeToken(this);
        }

        /// <summary>
        /// 加载配置数据
        /// </summary>
        public void Load()
        {
            _ = LoadConfigurationAsync();
        }

        /// <summary>
        /// 异步加载配置数据
        /// </summary>
        public async Task LoadAsync()
        {
            await LoadConfigurationAsync();
        }

        /// <summary>
        /// 异步加载配置数据
        /// </summary>
        private async Task LoadConfigurationAsync()
        {
            await _loadLock.WaitAsync();
            try
            {
                // 检查是否已经加载过（简单的时间戳检查）
                if (_data.ContainsKey("__loaded__"))
                {
                    return;
                }

                // 加载所有配置
                var configs = await _configurationAppService.GetListAsync(new GetConfigurationItemListInput
                {
                    MaxResultCount = 10000 // 获取大量配置
                });

                // 清空现有数据
                _data.Clear();

                // 转换为键值对
                foreach (var config in configs.Items)
                {
                    var key = $"{config.Namespace}:{config.Key}";
                    _data[key] = config.Value;

                    // 同时提供扁平键格式
                    var flatKey = $"{config.Namespace.Replace(".", ":")}:{config.Key}";
                    _data[flatKey] = config.Value;
                }

                // 标记为已加载
                _data["__loaded__"] = _clock.Now.ToString("O");
                _data["__last_loaded__"] = _clock.Now.Ticks.ToString();
            }
            finally
            {
                _loadLock.Release();
            }
        }

        /// <summary>
        /// 刷新配置
        /// </summary>
        public async Task ReloadAsync()
        {
            await _loadLock.WaitAsync();
            try
            {
                // 清除加载标记
                _data.TryRemove("__loaded__", out _);

                // 重新加载
                await LoadConfigurationAsync();
            }
            finally
            {
                _loadLock.Release();
            }
        }

        /// <summary>
        /// 添加或更新配置项
        /// </summary>
        public void AddOrUpdate(string @namespace, string name, string value)
        {
            var key = $"{@namespace}:{name}";
            _data[key] = value;

            // 同时更新扁平键格式
            var flatKey = $"{@namespace.Replace(".", ":")}:{name}";
            _data[flatKey] = value;
        }

        /// <summary>
        /// 移除配置项
        /// </summary>
        public void Remove(string key)
        {
            _data.TryRemove(key, out _);
        }

        /// <summary>
        /// 清除所有配置
        /// </summary>
        public void Clear()
        {
            _data.Clear();
        }
    }

    /// <summary>
    /// Matrix配置变更令牌
    /// </summary>
    public class MatrixConfigurationChangeToken : IChangeToken
    {
        private readonly MatrixConfigurationProvider _provider;
        private readonly List<Callback> _callbacks;
        private bool _hasChanged;

        public MatrixConfigurationChangeToken(MatrixConfigurationProvider provider)
        {
            _provider = provider;
            _callbacks = new List<Callback>();
            _hasChanged = false;
        }

        public bool HasChanged => _hasChanged;

        public bool ActiveChangeCallbacks => true;

        public IDisposable RegisterChangeCallback(Action<object?> callback, object? state)
        {
            var registration = new Callback(callback, state);
            _callbacks.Add(registration);
            return registration;
        }

        public void NotifyChanged()
        {
            _hasChanged = true;
            foreach (var callback in _callbacks)
            {
                callback.Invoke();
            }
            _callbacks.Clear();
        }

        private class Callback : IDisposable
        {
            private readonly Action<object?> _callback;
            private readonly object? _state;

            public Callback(Action<object?> callback, object? state)
            {
                _callback = callback;
                _state = state;
            }

            public void Dispose()
            {
                // 实现释放逻辑
            }

            public void Invoke()
            {
                _callback(_state);
            }
        }
    }
}